﻿using System;
using System.Linq;
using Castle.Core.Interceptor;
using Luna.Common.Extensions;
using Luna.Core.Extensions;

namespace XWord.Common.Attributes
{
    public class SuperRescueAttribute : HandleExceptionAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RescueAttribute"/> class.
        /// </summary>
        /// <param name="methodName">Name of the method.</param>
        public SuperRescueAttribute(string methodName)
            : base(methodName)
        { }

        public override bool Predicate(IInvocation invocation, Exception ex)
        {
            bool isReturnBool = invocation.TargetType.GetMethod(_methodName).ReturnType == typeof(bool);
            if (isReturnBool)
                return base.Func<bool>(invocation, _methodName, GetParameters(invocation, ex));
            else
                base.Action(invocation, _methodName, GetParameters(invocation, ex));
            return base.Predicate(invocation, ex);
        }

        private object[] GetParameters(IInvocation invocation, Exception ex)
        {
            var targetParameterInfo = invocation.MethodInvocationTarget.GetParameters();
            var rescueMethodParameterInfo = invocation.TargetType.GetMethod(_methodName).GetParameters();
            var param = invocation.Arguments.Add(ex).ToArray();
            return InvocationExtension.GetArguments(param, targetParameterInfo, rescueMethodParameterInfo);
        }
    }
}
